/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package boundaries;

import utils.NoWeatherException;
import utils.WeatherConverter;
import entities.City;
import utils.Weather;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.ejb.Stateless;
import org.primefaces.json.JSONArray;
import org.primefaces.json.JSONException;
import org.primefaces.json.JSONObject;

/**
 *
 * @author Alberto, Alessandra
 */
@Stateless
public class WeatherService {
    
    private static String starturl = "http://api.openweathermap.org/data/2.5/forecast/daily?q=";
    private static String trailerurl = "&cnt=16&mode=json";
    
    public Weather getWeatherForecast (City city, Date date) throws NoWeatherException {
        String city_name = city.getName();
        city_name = city_name.replace(" ", "_");
        String url = starturl + city_name + trailerurl;
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        
        try {
        
            JSONObject json = readJsonFromUrl(url);
            JSONArray jsonarray = json.getJSONArray("list");
            for (int i=0; i<jsonarray.length(); i++) {
                JSONObject jsonday = jsonarray.getJSONObject(i);
                Long datelong = Long.parseLong(jsonday.get("dt").toString());
                datelong = datelong * 1000;
                Date dateweather = new Date(datelong);
                GregorianCalendar gcweather = new GregorianCalendar();
                gcweather.setTime(dateweather);
                if(gcweather.get(Calendar.YEAR) == gc.get(Calendar.YEAR) && gcweather.get(Calendar.DAY_OF_YEAR) == gc.get(Calendar.DAY_OF_YEAR)){
                    JSONArray jsonweatherarray = jsonday.getJSONArray("weather");
                    JSONObject jsonweather = jsonweatherarray.getJSONObject(0);
                    Integer id = (Integer)jsonweather.get("id");
                    Weather weather = WeatherConverter.convertToWeatherEnum(id);
                    return weather;
                }
            }
        
        } catch (IOException e){
            throw new NoWeatherException();
        } catch(JSONException e){
            throw new NoWeatherException();
        }
        throw new NoWeatherException();
    }
    
    public Date getProposedDate (City city, Date date, ArrayList<Weather> badweather) throws NoWeatherException {
        String city_name = city.getName();
        city_name = city_name.replace(" ", "_");
        String url = starturl + city_name + trailerurl;
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        
        try {
        
            JSONObject json = readJsonFromUrl(url);
            JSONArray jsonarray = json.getJSONArray("list");
            for (int i=0; i<jsonarray.length(); i++) {
                JSONObject jsonday = jsonarray.getJSONObject(i);
                Long datelong = Long.parseLong(jsonday.get("dt").toString());
                datelong = datelong * 1000;
                Date dateweather = new Date(datelong);
                GregorianCalendar gcweather = new GregorianCalendar();
                gcweather.setTime(dateweather);
                JSONArray jsonweatherarray = jsonday.getJSONArray("weather");
                JSONObject jsonweather = jsonweatherarray.getJSONObject(0);
                Integer id = (Integer)jsonweather.get("id");
                Weather weather = WeatherConverter.convertToWeatherEnum(id);
                if (!badweather.contains(weather) && gcweather.compareTo(gc) > 0)
                    return dateweather;
            }
        
        } catch (IOException e){
            throw new NoWeatherException();
        } catch(JSONException e){
            throw new NoWeatherException();
        }
        throw new NoWeatherException();
    }
    
    private String readAll(Reader rd) throws IOException {
        StringBuilder sb = new StringBuilder();
        int cp;
        while ((cp = rd.read()) != -1) {
          sb.append((char) cp);
        }
        return sb.toString();
    }

    private JSONObject readJsonFromUrl(String url) throws IOException, JSONException {
        InputStream is = new URL(url).openStream();
        try {
          InputStreamReader isr = new InputStreamReader(is, Charset.forName("UTF-8"));
          BufferedReader rd = new BufferedReader(isr);
          String jsonText = readAll(rd);
          JSONObject json = new JSONObject(jsonText);
          return json;
        } finally {
          is.close();
        }
    }
    
}
